/**
 * $Id: ObjectIdUtils.java,v 1.4.26.8 2009/02/26 17:53:50 c052898 Exp $
 */
package com.angel.common.helpers;

import java.io.Serializable;

import org.hibernate.HibernateException;
import org.hibernate.engine.SessionImplementor;
import org.safehaus.uuid.UUID;

import com.angel.architecture.persistence.ids.ObjectId;
import com.angel.architecture.persistence.ids.generator.AbstractUUIDGenerator;
import com.angel.architecture.persistence.ids.impl.ObjectIdImpl;




/**
 * Singleton que provee ObjectIds
 */
public final class ObjectIdHelper {

    public static final ObjectIdHelper INSTANCE = new ObjectIdHelper();
    private Generator uuidStringGenerator;

    private ObjectIdHelper() {
        uuidStringGenerator = new Generator();
    }

    public static ObjectId createDummyObjectId(String semilla) {
        return new ObjectIdImpl(generateDummyObjectId(semilla));
    }

    /**
     * @return from 00a2105697dc9caa1807dc9caaa708087 build an ObjectID
     */
    public static ObjectId getIdFrom(String uuidString) {
        return new ObjectIdImpl(new UUID(uuidString));
    }

    public static ObjectId createObjectId() {
        return new ObjectIdImpl(generateObjectId());
    }

    static UUID generateObjectId() {
        return INSTANCE.uuidStringGenerator.generate();
    }

    static UUID generateDummyObjectId(String semilla) {
        return INSTANCE.uuidStringGenerator.generateDummy(semilla);
    }

    static class Generator extends AbstractUUIDGenerator {

        public UUID generate() {
            byte[] yIntBuffer = new byte[4];
            byte[] yShortBuffer = new byte[2];
            byte[] yResult = new byte[16];

            // ip
            yIntBuffer = this.toBytes(getIP());
            yResult[0] = yIntBuffer[0];
            yResult[1] = yIntBuffer[1];
            yResult[2] = yIntBuffer[2];
            yResult[3] = yIntBuffer[3];

            // jvm
            yIntBuffer = this.toBytes(getJVM());
            yResult[4] = yIntBuffer[0];
            yResult[5] = yIntBuffer[1];
            yResult[6] = yIntBuffer[2];
            yResult[7] = yIntBuffer[3];

            // high time
            yShortBuffer = this.toBytes(getHiTime());
            yResult[8] = yShortBuffer[0];
            yResult[9] = yShortBuffer[1];

            // low time
            yIntBuffer = this.toBytes(getLoTime());
            yResult[10] = yIntBuffer[0];
            yResult[11] = yIntBuffer[1];
            yResult[12] = yIntBuffer[2];
            yResult[13] = yIntBuffer[3];

            // counter
            yShortBuffer = this.toBytes(getCount());
            yResult[14] = yShortBuffer[0];
            yResult[15] = yShortBuffer[1];

            return new UUID(yResult);
        }

        public byte[] toBytes(int value) {
            byte[] result = new byte[4];
            for (int i=3; i>=0; i--) {
                result[i] = (byte) ( ( 0xFFl & value ) + Byte.MIN_VALUE );
                value >>>= 8;
            }
            return result;
        }

        public byte[] toBytes(short value) {
            byte[] result = new byte[2];
            for (int i=1; i>=0; i--) {
                result[i] = (byte) ( ( 0xFFl & value )  + Byte.MIN_VALUE );
                value >>>= 8;
            }
            return result;
        }

        /**
         * @param semilla
         * @return
         */
        public UUID generateDummy(String semilla) {
            int midle = semilla.length() / 2;
            byte[] yLongBuffer = new byte[8];
            byte[] yResult = new byte[16];

            yLongBuffer = toBytes(StringHelper.longHashCode(semilla.substring(0,midle)));
            yResult[0] = yLongBuffer[0];
            yResult[1] = yLongBuffer[1];
            yResult[2] = yLongBuffer[2];
            yResult[3] = yLongBuffer[3];

            yResult[4] = yLongBuffer[4];
            yResult[5] = yLongBuffer[5];
            yResult[6] = yLongBuffer[6];
            yResult[7] = yLongBuffer[7];


            yLongBuffer = toBytes(StringHelper.longHashCode(semilla.substring(midle)));
            yResult[8] = yLongBuffer[0];
            yResult[9] = yLongBuffer[1];
            yResult[10] = yLongBuffer[2];
            yResult[11] = yLongBuffer[3];
            yResult[12] = yLongBuffer[4];
            yResult[13] = yLongBuffer[5];
            yResult[14] = yLongBuffer[6];
            yResult[15] = yLongBuffer[7];

            return new UUID(yResult);
        }

        static byte[] toBytes(long value) {
            byte result[] = new byte[8];
            for ( int i = 7; i >= 0; i-- ) {
                result[i] = (byte) (int) ((255L & value) + -128L);
                value >>>= 8;
            }

            return result;
        }

        public Serializable generate(SessionImplementor session, Object object) throws HibernateException {
            // nothing to do
            return null;
        }
    }

	public static String getIdFromGUID(String tocectoryGUID) {
		String id = tocectoryGUID.substring(1,tocectoryGUID.length());
		int a = 0;
		int b = 8;
		String finalID = "";
		for (int i = 0; i < 4; i++) {
			finalID = finalID.concat(id.substring(a,b).concat("-"));
			a = b;
			b = b + 4;
			if(i==3){
				finalID = finalID.concat(id.substring(a,id.length()));
			}
		}
		return finalID.toLowerCase();
	}

}
